﻿using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;

using Winz.JsonModel;
using Winz.FoeBot.DataLayer;

/*
using Winz.DataSet;
using Winz.DataSet.foeDataSetTableAdapters;
*/
//using AutoItX3Lib;

namespace Winz.FoeBot
{





    public enum MotivateType
    {
        PO, MO, MM
    }

    public enum BotStateEnum
    {
        Started, Paused, Stopped
    }

    public class Bot : IDisposable
    {

        public static BotSettings settings;


        public static List<CityEntity> cityEntities;
        
/*
        private foeDataSet dataSet;
        private foe_city_entitiesTableAdapter taCitiyEntities;
*/
        public string windowsName;
        public string objectName;

        public Awesomium.Windows.Forms.WebControl webBrowser; 
        public ScrollableControl panel;
        
        public delegate void LogHandler(string txt, params object[] args);
        private LogHandler Log;

        public JsonParser jsonParser;
        public FoeDbUpdater dbUpdater;
        public Motivator socialBarMotivator;


        public  Bot() {

            Bot.settings = BotSettings.Load();

            jsonParser = new JsonParser();
            this.dbUpdater = new FoeDbUpdater(jsonParser);

            FiddlerWrapper.Start();
            FiddlerWrapper.FiddlerJsonRecieved += 
                    new FiddlerJsonRecievedEventHandler((object o, MessageEventArgs<string> e) =>{
                        jsonParser.parse(e.Message);
                    });
            FiddlerWrapper.FoeErrorSent +=
                    new EventHandler((object o, EventArgs e) =>
                    {

                        webBrowser.InvokeIfRequired(w => w.Reload(false));
                        
                        new Thread(new ThreadStart(() => {
                            Thread.Sleep(2000);
                            socialBarMotivator.Stop();
                            socialBarMotivator.Start();
                        }));

                    });
       }


        public Bot(string windowsName,string objectName,LogHandler logger) : this() {
            this.windowsName = windowsName;
            this.objectName = objectName;
            this.Log = logger;


            socialBarMotivator = new Motivator(this.Click,this.Click);
            socialBarMotivator.Log = Log;
            socialBarMotivator.Click = Click;

            jsonParser.GameStarted += new GameStartedEventHandler(OnGameStarted);
            jsonParser.PlayerListRecieved += new PlayerListRecievedEventHandler(socialBarMotivator.OnPlayerListRecieved);
            jsonParser.PlayerVisited += new PlayerVisitedEventHandler(socialBarMotivator.OnPlayerVisited);
            jsonParser.PlayerMotivated += new PlayerMotivatedEventHandler(socialBarMotivator.OnPlayerMotivated);
            jsonParser.BluePrintFound += new BluePrintFoundEventHandler(OnBluePrintFound);

        }

        


        public void Dispose()
        {
            this.socialBarMotivator.Stop();
            FiddlerWrapper.Stop();
        }
        
        public void OnGameStarted(object sender, MessageEventArgs<StartUp> e)
        {
            Log("Game started");
            Bot.cityEntities = e.Message.CityEntities.ToList();
            jsonParser.EventsRecieved += new EventsRecievedEventHandler(OnEventsRecieved);
            socialBarMotivator.UpdatePlayers(e.Message.SocialbarList);
        }


        public void OnEventsRecieved(object sender, MessageEventArgs<List<Interaction>> e)
        {
            Log("Events Found");
            new Thread(() =>
            {
                webBrowser.SetBotMode(true);
                Thread.Sleep(500);
                Click(Bot.settings.closeNewEventBtn);
                Thread.Sleep(500);
                Click(Bot.settings.closeEventsBtn);
            }).Start();
        }
        
        public void OnBluePrintFound(object sender, BluePrintFoundEventArgs e)
        {
            Log("Blue Print Found");
            new Thread(() =>
            {
                Thread.Sleep(500);
                Click(Bot.settings.bluePrintFoundCloseBtn);
                Thread.Sleep(500);
                jsonParser.RaisePlayerMotivated(this,new MessageEventArgs<OtherPlayer>(e.Player));
            }).Start();
            
        }


/*

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle);
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

        public enum WMessages : int
        {
            WM_LBUTTONDOWN = 0x201,
            WM_LBUTTONUP = 0x202,
            WM_MOUSEMOVE = 0x0200
        }
        private int MAKELPARAM(int p, int p_2)
        {
            return ((p_2 << 16) | (p & 0xFFFF));
        }


        public IntPtr Flash(Awesomium.Windows.Forms.WebControl w)
        {
            IntPtr pControl;
            pControl = FindWindowEx(w.Handle, IntPtr.Zero, "Shell Embedding", IntPtr.Zero);
            pControl = FindWindowEx(pControl, IntPtr.Zero, "Shell DocObject View", IntPtr.Zero);
            pControl = FindWindowEx(pControl, IntPtr.Zero, "Internet Explorer_Server", IntPtr.Zero);
            pControl = FindWindowEx(pControl, IntPtr.Zero, "MacromediaFlashPlayerActiveX", IntPtr.Zero);
            return pControl;
        }


        public void DoMouseLeftClick(IntPtr handle, int x,int y)
        {
            PostMessage(handle, (uint)WMessages.WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
            Thread.Sleep(200);
            PostMessage(handle, (uint)WMessages.WM_LBUTTONUP, 0, MAKELPARAM(x, y));
            
            PostMessage(handle, (uint)WMessages.WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
            PostMessage(handle, (uint)WMessages.WM_LBUTTONUP, 0, MAKELPARAM(x, y));
            
        }


        delegate int ClickDelegate(int x, int y);
*/
        
        public void Click(int x, int y)
        {
            webBrowser.LeftClick(x, y);
        }


        public void Click(Point p) {
            Click(p.X, p.Y);
        }

        public void Click(Entity batiment)
        {
            var row = cityEntities.Single(ci => ci.Id == batiment.CityentityId);
            Log("Clicking {0} ( {1},{2})", row.Name, batiment.X, batiment.Y);
            ClickMap(batiment.X + row.Width / 2, batiment.Y + row.Length / 2);
        }


        public void ClickMap(float x, float y)
        {
            MapPoint mapPoint = new MapPoint(x, y);
            Point browserPoint = mapPoint.toBrowserPoint();
            Log("ClickMap ({0};{1}) => ({2};{3})", x, y, browserPoint.X, browserPoint.Y);
            Click(browserPoint.X, browserPoint.Y);


        }

        public void ClickMotivate()
        {
            Click(Bot.settings.motivateBtn);
        }

        public void ClickPolish()
        {
            Click(Bot.settings.polishBtn);
        }


    }
}
